<script>
export default {
  name: 'LayoutHistory'
}
</script>

<template>
  <div id="layoutHistory">
    <div class="box-history">
      <div class="menu-total" @click="totalCollapse">
        <div v-if="isCollapse" class="gvaIcon gvaIcon-arrow-double-right" />
        <div v-else class="gvaIcon gvaIcon-arrow-double-left" />
      </div>
      <el-scrollbar>
        <el-tabs
          v-model="activeValue"
          :closable="!(historys.length === 1 && $route.name === defaultRouter)"
          type="card"
          @contextmenu.prevent="openContextMenu($event)"
          @tab-click="changeTab"
          @tab-remove="removeTab"
        >
          <el-tab-pane
            v-for="item in historys"
            :key="item"
            :label="item.meta.title"
            :name="name(item)"
            :tab="item"
            class="gva-tab"
          >
            <template #label>
              <span :tab="item" :style="{ color: activeValue === name(item) ? userStore.activeColor : '#333', }">
                <i class="dot" :style="{ backgroundColor: activeValue === name(item) ? userStore.activeColor : '#082754', }" />
                {{ fmtTitle(item.meta.title, item) }}
              </span>
            </template>
          </el-tab-pane>
        </el-tabs>
      </el-scrollbar>
      <ul
        v-show="contextMenuVisible"
        :style="{ left: left + 'px', top: top + 'px' }"
        class="contextmenu"
      >
        <li @click="closeAll">关闭所有</li>
        <li @click="closeLeft">关闭左侧</li>
        <li @click="closeRight">关闭右侧</li>
        <li @click="closeOther">关闭其他</li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { emitter } from '@/utils/bus.js'
import { computed, onUnmounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/pinia/modules/user'
import { fmtTitle } from '@/utils/fmtRouterTitle'

const route = useRoute()
const router = useRouter()

const getFmtString = (item) => {
  return item.name + JSON.stringify(item.query) + JSON.stringify(item.params)
}

const historys = ref([])
const activeValue = ref('')
const contextMenuVisible = ref(false)

const userStore = useUserStore()

const name = (item) => {
  return (
    item.name + JSON.stringify(item.query) + JSON.stringify(item.params)
  )
}

const left = ref(0)
const top = ref(0)
const isCollapse = ref(false)
const isMobile = ref(false)
const rightActive = ref('')
const defaultRouter = computed(() => userStore.userInfo.authority.defaultRouter)
const openContextMenu = (e) => {
  if (
    historys.value.length === 1 &&
      route.name === defaultRouter.value
  ) {
    return false
  }
  let id = ''
  if (e.srcElement.nodeName === 'SPAN') {
    id = e.srcElement.offsetParent.id
  } else {
    id = e.srcElement.id
  }
  if (id) {
    contextMenuVisible.value = true
    let width
    if (isCollapse.value) {
      width = 54
    } else {
      width = 220
    }
    if (isMobile.value) {
      width = 0
    }
    left.value = e.clientX - width + 5
    top.value = e.clientY - 30
    rightActive.value = id.substring(4)
  }
}
const closeAll = () => {
  historys.value = [
    {
      name: defaultRouter.value,
      meta: {
        title: '首页',
      },
      query: {},
      params: {},
    },
  ]
  router.push({ name: defaultRouter.value })
  contextMenuVisible.value = false
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
}
const closeLeft = () => {
  let right
  const rightIndex = historys.value.findIndex((item) => {
    if (getFmtString(item) === rightActive.value) {
      right = item
    }
    return getFmtString(item) === rightActive.value
  })
  const activeIndex = historys.value.findIndex(
    (item) => getFmtString(item) === activeValue.value
  )
  historys.value.splice(0, rightIndex)
  if (rightIndex > activeIndex) {
    router.push(right)
  }
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
}
const closeRight = () => {
  let right
  const leftIndex = historys.value.findIndex((item) => {
    if (getFmtString(item) === rightActive.value) {
      right = item
    }
    return getFmtString(item) === rightActive.value
  })
  const activeIndex = historys.value.findIndex(
    (item) => getFmtString(item) === activeValue.value
  )
  historys.value.splice(leftIndex + 1, historys.value.length)
  if (leftIndex < activeIndex) {
    router.push(right)
  }
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
}
const closeOther = () => {
  let right
  historys.value = historys.value.filter((item) => {
    if (getFmtString(item) === rightActive.value) {
      right = item
    }
    return getFmtString(item) === rightActive.value
  })
  router.push(right)
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
}
const isSame = (route1, route2) => {
  if (route1.name !== route2.name) {
    return false
  }
  if (Object.keys(route1.query).length !== Object.keys(route2.query).length || Object.keys(route1.params).length !== Object.keys(route2.params).length) {
    return false
  }
  for (const key in route1.query) {
    if (route1.query[key] !== route2.query[key]) {
      return false
    }
  }
  for (const key in route1.params) {
    if (route1.params[key] !== route2.params[key]) {
      return false
    }
  }
  return true
}
const setTab = (route) => {
  if (!historys.value.some((item) => isSame(item, route))) {
    const obj = {}
    obj.name = route.name
    obj.meta = { ...route.meta }
    delete obj.meta.matched
    obj.query = route.query
    obj.params = route.params
    historys.value.push(obj)
  }
  window.sessionStorage.setItem('activeValue', getFmtString(route))
}

const historyMap = ref({})

const changeTab = (TabsPaneContext) => {
  const name = TabsPaneContext?.props?.name
  if (!name) return
  const tab = historyMap.value[name]
  router.push({
    name: tab.name,
    query: tab.query,
    params: tab.params,
  })
}
const removeTab = (tab) => {
  const index = historys.value.findIndex(
    (item) => getFmtString(item) === tab
  )
  if (getFmtString(route) === tab) {
    if (historys.value.length === 1) {
      router.push({ name: defaultRouter.value })
    } else {
      if (index < historys.value.length - 1) {
        router.push({
          name: historys.value[index + 1].name,
          query: historys.value[index + 1].query,
          params: historys.value[index + 1].params,
        })
      } else {
        router.push({
          name: historys.value[index - 1].name,
          query: historys.value[index - 1].query,
          params: historys.value[index - 1].params,
        })
      }
    }
  }
  historys.value.splice(index, 1)
}

watch(() => contextMenuVisible.value, () => {
  if (contextMenuVisible.value) {
    document.body.addEventListener('click', () => {
      contextMenuVisible.value = false
    })
  } else {
    document.body.removeEventListener('click', () => {
      contextMenuVisible.value = false
    })
  }
})

watch(() => route, (to, now) => {
  if (to.name === 'Login' || to.name === 'Reload') {
    return
  }
  historys.value = historys.value.filter((item) => !item.meta.closeTab)
  setTab(to)
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
  activeValue.value = window.sessionStorage.getItem('activeValue')
}, { deep: true })

watch(() => historys.value, () => {
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
  historyMap.value = {}
  historys.value.forEach((item) => {
    historyMap.value[getFmtString(item)] = item
  })
  emitter.emit('setKeepAlive', historys.value)
}, {
  deep: true
})

const collapse = ref(false)
const isSider = ref(true)
const isShadowBg = ref(false)
const totalCollapse = () => {
  isCollapse.value = !isCollapse.value
  isSider.value = !isCollapse.value
  isShadowBg.value = !isCollapse.value
  emitter.emit('collapse', isCollapse.value)
}

const initPage = () => {
  emitter.on('closeThisPage', () => {
    removeTab(name(route))
  })
  emitter.on('closeAllPage', () => {
    closeAll()
  })
  emitter.on('mobile', (data) => {
    isMobile.value = data
  })
  emitter.on('collapse', (data) => {
    isCollapse.value = data
  })
  const initHistorys = [
    {
      name: defaultRouter.value,
      meta: {
        title: '首页',
      },
      query: {},
      params: {},
    },
  ]
  historys.value =
      JSON.parse(sessionStorage.getItem('historys')) || initHistorys
  if (!window.sessionStorage.getItem('activeValue')) {
    activeValue.value = getFmtString(route)
  } else {
    activeValue.value = window.sessionStorage.getItem('activeValue')
  }
  setTab(route)
  if (window.sessionStorage.getItem('needCloseAll') === 'true') {
    closeAll()
    window.sessionStorage.removeItem('needCloseAll')
  }
}
initPage()

onUnmounted(() => {
  emitter.off('collapse')
  emitter.off('mobile')
})
</script>

<style lang="scss">
@import '@/view/xidw/xidwHistory/LayoutHistory.scss';
</style>
